package me.zhengjie.modules.customer.service.impl;

import me.zhengjie.modules.customer.domain.TCustomerContract;
import me.zhengjie.modules.customer.domain.TCustomerInfo;
import me.zhengjie.modules.customer.repository.TCustomerInfoRepository;
import me.zhengjie.modules.system.domain.DictDetail;
import me.zhengjie.modules.system.repository.DictDetailRepository;
import me.zhengjie.utils.ValidationUtil;
import me.zhengjie.modules.customer.repository.TCustomerContractRepository;
import me.zhengjie.modules.customer.service.TCustomerContractService;
import me.zhengjie.modules.customer.service.dto.TCustomerContractDTO;
import me.zhengjie.modules.customer.service.dto.TCustomerContractQueryCriteria;
import me.zhengjie.modules.customer.service.mapper.TCustomerContractMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.Optional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import me.zhengjie.utils.PageUtil;
import me.zhengjie.utils.QueryHelp;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

/**
* @author xuyukun
* @date 2019-07-21
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class TCustomerContractServiceImpl implements TCustomerContractService {
    @Autowired
    private DictDetailRepository dictDetailRepository;
    @Autowired
    private TCustomerInfoRepository tCustomerInfoRepository;
    @Autowired
    private TCustomerContractRepository tCustomerContractRepository;

    @Autowired
    private TCustomerContractMapper tCustomerContractMapper;

    @Override
    public Object queryAll(TCustomerContractQueryCriteria criteria, Pageable pageable){
        Page<TCustomerContract> page = tCustomerContractRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(tCustomerContractMapper::toDto));
    }

    @Override
    public Object queryAll(TCustomerContractQueryCriteria criteria){
        return tCustomerContractMapper.toDto(tCustomerContractRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    public TCustomerContractDTO findById(Long id) {
        Optional<TCustomerContract> tCustomerContract = tCustomerContractRepository.findById(id);
        ValidationUtil.isNull(tCustomerContract,"TCustomerContract","id",id);
        return tCustomerContractMapper.toDto(tCustomerContract.get());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TCustomerContractDTO create(TCustomerContract resources) {
        operateObject(resources);
        return tCustomerContractMapper.toDto(tCustomerContractRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(TCustomerContract resources) {
        Optional<TCustomerContract> optionalTCustomerContract = tCustomerContractRepository.findById(resources.getId());
        ValidationUtil.isNull( optionalTCustomerContract,"TCustomerContract","id",resources.getId());

        TCustomerContract tCustomerContract = optionalTCustomerContract.get();
        // 此处需自己修改
        resources.setId(tCustomerContract.getId());

        operateObject(resources);
        tCustomerContractRepository.save(resources);
    }

    private void operateObject(TCustomerContract resources) {
        // Timestamp date = new Timestamp(System.currentTimeMillis());
        // resources.setCreatTime(date); 签订时间
        DictDetail dictDetailDTO = dictDetailRepository.findById(Long.valueOf(resources.getContractItemId())).get();
        if (dictDetailDTO != null) {
            resources.setContractItemName(dictDetailDTO.getLabel());
        }
        TCustomerInfo optionalTCustomerInfo = tCustomerInfoRepository.findById(Long.valueOf(resources.getCustomerId())).get();
        if (optionalTCustomerInfo != null) {
            resources.setCustomerName(optionalTCustomerInfo.getCustomerName());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        tCustomerContractRepository.deleteById(id);
    }


    private Specification getPredicate(Long contractItemId, Long customerId, String effectTime) {
        Specification specification = new Specification() {
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) {
                //增加筛选条件
                Predicate predicate = QueryHelp.getPredicate(root, query, cb);

                predicate.getExpressions().add(cb.greaterThanOrEqualTo(root.get("endTime").as(String.class), effectTime));

                predicate.getExpressions().add(cb.lessThanOrEqualTo(root.get("startTime").as(String.class),  effectTime));

                predicate.getExpressions().add(cb.equal(root.get("contractItemId").as(Long.class), contractItemId));

                predicate.getExpressions().add(cb.equal(root.get("customerId").as(Long.class), customerId));

                return predicate;
            }
        };
        return specification;
    }


    @Override
    public Optional<TCustomerContract> findLastEffectContract(Long contractItemId, Long customerId, String effectTime) {
        Specification specification = getPredicate(contractItemId, customerId, effectTime);
        return tCustomerContractRepository.findOne(specification);
    }
}